import pylab, NodeModel, NodeView;
from PyQt4 import QtCore, QtGui;

class NodeController(QtGui.QGraphicsObject, object):
    def __init__(self, xP=0, yP=0):
        super(NodeController, self).__init__();
        self.nodeModel = NodeModel.NodeModel();
        self.nodeView = NodeView.NodeView(self);
        self.setPos(QtCore.QPointF(xP, yP));
        self.oldPos, self.newPos = self.pos(), self.pos();
        self.actions, self.inEdges, self.outEdges = [], [], [];
        self.qTxtStateName, self.qTxtReward = None, None;
        self.qTxtValue, self.stateShape = None, None;
        self.createNode();
                        
    []#Add/Remove In/Out/All Edges
    def addInEdge(self, edge): 
        if self.inEdges.count(edge)==0:
            self.inEdges.append(edge);
    
    def removeInEdge(self, edge):
        if self.inEdges.count(edge)>0:
            self.inEdges.remove(edge);
              
    def addOutEdge(self, edge):
        if self.outEdges.count(edge)==0:
            self.outEdges.append(edge);
    
    def removeOutEdge(self, edge):
        if self.outEdges.count(edge)>0:
            self.outEdges.remove(edge);
        
    def addAllEdges(self, inEdges, outEdges):
        for inEdge in inEdges:
            inEdge.addEdge();
        for outEdge in outEdges:
            outEdge.addEdge();
    
    def removeAllEdges(self):
        for i in range(len(self.inEdges)-1,-1, -1):
            self.inEdges[i].removeEdge();
        for action in self.actions:
            for i in range(len(action.outEdges)-1,-1, -1):
                action.outEdges[i].removeEdge();
            
    def getInEdges(self):
        inEdges = [];
        for inEdge in self.inEdges:
            inEdges.append(inEdge);
        return inEdges;
            
    def getOutEdges(self):
        outEdges = [];
        for outEdge in self.outEdges:
            outEdges.append(outEdge);
        return outEdges;
    
    []#Give Outline Node Position for In-Edges
    def prepareNodePosEdgeData(self):
        self.nSteps = 15;
        self.intersectPoint = QtCore.QPointF();
        self.nodeRegion = self.nodeView.getNodeRegion();
        self.aPercent = pylab.linspace(0,1,self.nSteps);

    def getNodePos(self, sourcePos):
        targetPos = QtCore.QPointF(self.pos().x()+80, self.pos().y()+80);
        centerLine = QtCore.QLineF(sourcePos, targetPos);
        for i in range(self.nSteps-1):
            p1 = self.mapToScene(self.nodeRegion.pointAtPercent(self.aPercent[i]));
            p2 = self.mapToScene(self.nodeRegion.pointAtPercent(self.aPercent[i+1]));
            polyLine = QtCore.QLineF(p1, p2);
            intersectType = polyLine.intersect(centerLine, self.intersectPoint);
            if intersectType == QtCore.QLineF.BoundedIntersection:
                break;
        return self.intersectPoint;
    
    def getNodePos_From(self):
        return QtCore.QPointF(self.pos().x()+80, self.pos().y()+80);
    
    []#Shape/BoundingRect for Displaying Node Region    
    def shape(self):
        return self.nodeView.getNodeRegion();
    
    def boundingRect(self):
        return self.nodeView.getBoundingRect();
   
    []#Creating the State Shape, Text Values & Actions    
    def createNode(self):
        self.nodeView.createNodeView();
        self.prepareNodePosEdgeData();
        
    def setActions(self, actions):
        self.actions = actions;
        
    def itemChange(self, change, value):
        if change == QtGui.QGraphicsItem.ItemSelectedHasChanged:
            self.nodeView.setSelectedStyle(self.isSelected());
        return QtGui.QGraphicsItem.itemChange(self, change, value);
    
    def paint(self, painter, option, widget):
        self.nodeView.refreshStateTxts();
        return;
    
    []#Mouse/Keyboard Events
    def mousePressEvent(self, event):
        super(NodeController, self).mousePressEvent(event);
        self.nodeView.setPressedStyle(True);
        
    def mouseReleaseEvent(self, event):
        super(NodeController, self).mouseReleaseEvent(event);
        self.nodeView.setPressedStyle(False);
